/* eslint-disable no-unused-vars */
import { TOKEN_KEY } from './constants'
import { BaseUrl } from './config.js'
export const log =
  process.env.NODE_ENV == 'development' ? console.log : () => {}

export const mergeObject = function (a, b) {
  for (let k in a) {
    a[k] = b[k] == null || b[k] == undefined ? a[k] : b[k]
  }
  return a
}

export const getStorageKey = function (KEY) {
  return uni.getStorageSync(KEY) ? uni.getStorageSync(KEY) : null
}

export const isRepeat = function (arr) {
  let setArr = Array.from(new Set(arr))
  return setArr.length == arr.length ? false : true
}

export const prefixPad = function (num, n, pad = '0') {
  var len = num.toString().length
  while (len < n) {
    num = pad + num
    len++
  }
  return num
}

export const dateFormat = function (date, fmt) {
  if (!(date instanceof Date)) {
    date = new Date(date)
  }
  var o = {
    'M+': date.getMonth() + 1, //月份
    'd+': date.getDate(), //日
    'h+': date.getHours(), //小时
    'm+': date.getMinutes(), //分
    's+': date.getSeconds(), //秒
    'q+': Math.floor((date.getMonth() + 3) / 3), //季度
    S: date.getMilliseconds(), //毫秒
  }
  if (/(y+)/.test(fmt))
    fmt = fmt.replace(
      RegExp.$1,
      (date.getFullYear() + '').substr(4 - RegExp.$1.length)
    )
  for (var k in o)
    if (new RegExp('(' + k + ')').test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      )
  return fmt
}

// 返回几分钟前
export const getDateDiff = function (dateTimeStamp) {
  let result = ''
  let minute = 1000 * 60
  let hour = minute * 60
  let day = hour * 24
  let month = day * 30
  let year = month * 12
  let now = new Date().getTime()
  dateTimeStamp = Date.parse(new Date(dateTimeStamp))
  let diffValue = now - dateTimeStamp
  if (diffValue < 0) return
  let yearC = diffValue / year
  let monthC = diffValue / month
  let weekC = diffValue / (7 * day)
  let dayC = diffValue / day
  let hourC = diffValue / hour
  let minC = diffValue / minute
  if (yearC >= 1) {
    result = '' + parseInt(yearC) + '年前'
  } else if (monthC >= 1) {
    result = '' + parseInt(monthC) + '月前'
  } else if (weekC >= 1) {
    result = '' + parseInt(weekC) + '周前'
  } else if (dayC >= 1) {
    result = '' + parseInt(dayC) + '天前'
  } else if (hourC >= 1) {
    result = '' + parseInt(hourC) + '小时前'
  } else if (minC >= 1) {
    result = '' + parseInt(minC) + '分钟前'
  } else {
    result = '刚刚'
  }
  return result
}

// 对话框
export const showConfirm = function (params) {
  const { t, content, confirmText, cancelColor, confirmColor } = params
  return new Promise((resolve, reject) => {
    uni.showModal({
      title: t,
      content: content,
      confirmText: confirmText ? confirmText : '确定',
      cancelColor: cancelColor ? cancelColor : '#C0C0C0',
      confirmColor: confirmColor ? confirmColor : '#222222',
      success: res => {
        resolve(res)
      },
    })
  })
}

// 返回几分钟前
export const formatDate = function (value) {
  var date = new Date(value)
  var y = date.getFullYear(),
    m = date.getMonth() + 1,
    d = date.getDate(),
    h = date.getHours(),
    i = date.getMinutes(),
    s = date.getSeconds()
  if (m < 10) {
    m = '0' + m
  }
  if (d < 10) {
    d = '0' + d
  }
  if (h < 10) {
    h = '0' + h
  }
  if (i < 10) {
    i = '0' + i
  }
  if (s < 10) {
    s = '0' + s
  }
  var t = y + '-' + m + '-' + d + ' ' + h + ':' + i + ':' + s
  return t
}

// 上传图片
export const handleUpload = function (callback) {
  let _this = this
  uni.chooseImage({
    count: 1,
    success: async res => {
      try {
        // #ifdef APP-PLUS
        const isPicture =
          res.tempFiles[0].path.includes('jpg') ||
          res.tempFiles[0].path.includes('png') ||
          res.tempFiles[0].path.includes('jpeg')
        // #endif
        // #ifdef H5
        const isPicture =
          res.tempFiles[0].name.includes('jpg') ||
          res.tempFiles[0].name.includes('png') ||
          res.tempFiles[0].name.includes('jpeg')
        // #endif
        const isLt2M = res.tempFiles[0].size / 1024 / 1024 < 1
        if (!isLt2M) {
          uni.showToast({
            title: '上传图片大小不能超过1MB',
            icon: 'none',
          })
          return
        }
        if (res.errMsg == 'chooseImage:ok') {
          uni.uploadFile({
            url: BaseUrl + 'oss/oss/upload',
            filePath: res.tempFilePaths[0],
            header: { Authorization: getStorageKey(TOKEN_KEY) },
            name: 'file',
            formData: {
              needStore: 1,
            },
            success: uploadFileRes => {
              if (
                uploadFileRes.statusCode == 200 &&
                uploadFileRes.errMsg == 'uploadFile:ok'
              ) {
                let result = JSON.parse(uploadFileRes.data)
                if (result.code == 0) {
                  callback(result)
                } else {
                  uni.showToast({
                    title: result.message,
                    icon: 'none',
                  })
                }
              } else {
                uni.showToast({
                  title: '上传失败',
                  icon: 'none',
                })
              }
            },
          })
        } else {
          uni.showToast({
            title: '选取失败',
            icon: 'none',
          })
        }
      } catch (e) {
        log(e)
      }
    },
  })
}

//打开第三方地图
export const toMapAPP = function (latitude, longitude, name) {
  let url = ''
  if (plus.os.name == 'Android') {
    //判断是安卓端
    plus.nativeUI.actionSheet(
      {
        //选择菜单
        title: '选择地图应用',
        cancel: '取消',
        buttons: [
          { title: '腾讯地图' },
          { title: '百度地图' },
          { title: '高德地图' },
        ],
      },
      function (e) {
        switch (e.index) {
          //下面是拼接url,不同系统以及不同地图都有不同的拼接字段
          case 1:
            //注意referer=xxx的xxx替换成你在腾讯地图开发平台申请的key
            url = `qqmap://map/geocoder?coord=${latitude},${longitude}&referer=xxx`
            break
          case 2:
            url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo`
            break
          case 3:
            url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`
            break
          default:
            break
        }
        if (url != '') {
          url = encodeURI(url)
          //plus.runtime.openURL(url,function(e){})调起手机APP应用
          plus.runtime.openURL(url, function (e) {
            plus.nativeUI.alert('本机未安装指定的地图应用')
          })
        }
      }
    )
  } else {
    // iOS上获取本机是否安装了百度高德地图，需要在manifest里配置
    // 在manifest.json文件app-plus->distribute->apple->urlschemewhitelist节点下添加
    //（如urlschemewhitelist:["iosamap","baidumap"]）
    plus.nativeUI.actionSheet(
      {
        title: '选择地图应用',
        cancel: '取消',
        buttons: [
          { title: '腾讯地图' },
          { title: '百度地图' },
          { title: '高德地图' },
        ],
      },
      function (e) {
        switch (e.index) {
          case 1:
            url = `qqmap://map/geocoder?coord=${latitude},${longitude}&referer=xxx`
            break
          case 2:
            url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`
            break
          case 3:
            url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`
            break
          default:
            break
        }
        if (url != '') {
          url = encodeURI(url)
          plus.runtime.openURL(url, function (e) {
            plus.nativeUI.alert('本机未安装指定的地图应用')
          })
        }
      }
    )
  }
}

/**
 * 对象数组去重,type表示对象里面的一个属性
 */
export const uniqueFun = function (arr, type) {
  const res = new Map()
  return arr.filter(a => !res.has(a[type]) && res.set(a[type], 1))
}

/**
 * 对象数组去重
 * @param {any} array:数组
 * @param {any} field:去重字段
 */
export const arrayToDistinct = function (array, field) {
  let obj = {}
  array = array.reduce((cur, next) => {
    obj[next.id] ? '' : (obj[next.id] = true && array.push(next))
    return cur
  }, []) //设置cur默认类型为数组,并且初始值为空的数组
  return array
}
/**
 * 参数处理
 */
export function tansParams(params) {
  let result = ''
  for (const propName of Object.keys(params)) {
    const value = params[propName]
    var part = encodeURIComponent(propName) + '='
    if (value !== null && typeof value !== 'undefined') {
      if (typeof value === 'object') {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && typeof value[key] !== 'undefined') {
            let params = propName + '[' + key + ']'
            var subPart = encodeURIComponent(params) + '='
            result += subPart + encodeURIComponent(value[key]) + '&'
          }
        }
      } else {
        result += part + encodeURIComponent(value) + '&'
      }
    }
  }
  return result
}

// 节流
export const throttle = (fn, delay) => {
  let timer = null
  return (...params) => {
    if (!timer) {
      timer = setTimeout(() => {
        fn(...params)
        timer = null
      }, delay)
    }
  }
}

// 防抖
// export const debounce = (fn, delay) => {
//   let timer = null
//   return (...param) => {
//     if (timer) clearTimeout(timer)
//     timer = setTimeout(() => {
//       fn(...param)
//     }, delay)
//   }
// }

// 第一个参数是需要进行防抖处理的函数，第二个参数是延迟时间，默认为1秒钟
// 这里多传一个参数，immediate用来决定是否要第一次立即执行, 默认为false
export const debounce = (fn, delay = 1000, immediate = false, resultCb) => {
  // 实现防抖函数的核心是使用setTimeout
  // time变量用于保存setTimeout返回的Id
  let time = null
  // isImmediateInvoke变量用来记录是否立即执行, 默认为false
  let isImmediateInvoke = false

  // 将回调接收的参数保存到args数组中
  function _debounce(...args) {
    // 如果time不为0，也就是说有定时器存在，将该定时器清除
    if (time !== null) {
      clearTimeout(time)
    }

    // 当是第一次触发，并且需要触发第一次事件
    if (!isImmediateInvoke && immediate) {
      // 将函数的返回值保存到result中
      const result = fn.apply(this, args)
      if (typeof resultCb === 'function') {
        // 当用户传递了resultCb函数时，执行该函数，并将结果以参数传递出去。
        resultCb(result)
      }
      // 将isImmediateInvoke设置为true，这样不会影响到后面频繁触发的函数调用
      isImmediateInvoke = true
    }

    time = setTimeout(() => {
      // 使用apply改变fn的this，同时将参数传递给fn
      fn.apply(this, args)
      // 当定时器里的函数执行时，也就是说是频繁触发事件的最后一次事件
      // 将isImmediateInvoke设置为false，这样下一次的第一次触发事件才能被立即执行
      isImmediateInvoke = false
    }, delay)
  }

  // 防抖函数会返回另一个函数，该函数才是真正被调用的函数
  return _debounce
}

export const getRect = selector => {
  return new Promise(resolve => {
    let view = uni.createSelectorQuery().select(selector)
    view
      .fields(
        {
          size: true,
          rect: true,
          scrollOffset: true,
        },
        res => {
          resolve(res)
        }
      )
      .exec()
  })
}

export default {
  log,
  mergeObject,
  isRepeat,
  prefixPad,
  dateFormat,
  getStorageKey,
  showConfirm,
  getDateDiff,
  handleUpload,
  toMapAPP,
  tansParams,
  uniqueFun,
  arrayToDistinct,
  debounce,
  throttle,
}
